home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / telecomm / sticpsrc.lzh / SOURCE.ARC / AX25DUMP.C < prev    next >
C/C++ Source or Header  |  1990-05-12  |  8KB  |  319 lines

  1. #include <stdio.h>
  2. #include "global.h"
  3. #include "mbuf.h"
  4. #include "ax25.h"
  5. #include "timer.h"
  6. #include "lapb.h"
  7. #include "ip.h"
  8. #include "trace.h"
  9.  
  10. extern FILE *trfp;
  11.  
  12. /* Dump an AX.25 packet header */
  13. ax25_dump(bpp)
  14. struct mbuf **bpp;
  15. {
  16.     char *decode_type();
  17.     char tmp[20];
  18.     char control,pid;
  19.     int16 type,ftype();
  20.     struct ax25 hdr;
  21.     struct ax25_addr *hp;
  22.  
  23.     fprintf(trfp,"AX25: ");
  24.     /* Extract the address header */
  25.     if(ntohax25(&hdr,bpp) < 0){
  26.         /* Something wrong with the header */
  27.         fprintf(trfp,"bad header!\n");
  28.         return;
  29.     }
  30.     pax25(tmp,&hdr.source);
  31.     fprintf(trfp,"%s",tmp);
  32.     pax25(tmp,&hdr.dest);
  33.     fprintf(trfp,"->%s",tmp);
  34.     if(hdr.ndigis > 0){
  35.         fprintf(trfp," v");
  36.         for(hp = &hdr.digis[0]; hp < &hdr.digis[hdr.ndigis]; hp++){
  37.             /* Print digi string */
  38.             pax25(tmp,hp);
  39.             fprintf(trfp," %s%s",tmp,(hp->ssid & REPEATED) ? "*":"");
  40.         }
  41.     }
  42.     if(pullup(bpp,&control,1) != 1){
  43.         fprintf(trfp," no control!\n");
  44.         return;
  45.     }
  46.  
  47.     type = ftype(control);
  48.     fprintf(trfp," %s",decode_type(type));
  49.     /* Dump poll/final bit */
  50.     if(control & PF){
  51.         switch(hdr.cmdrsp){
  52.         case COMMAND:
  53.             fprintf(trfp,"(P)");
  54.             break;
  55.         case RESPONSE:
  56.             fprintf(trfp,"(F)");
  57.             break;
  58.         default:
  59.             fprintf(trfp,"(P/F)");
  60.             break;
  61.         }
  62.     }
  63.     /* Dump sequence numbers */
  64.     if((type & 0x3) != U)    /* I or S frame? */
  65.         fprintf(trfp," NR=%d",(control>>5)&7);
  66.     if(type == I || type == UI){
  67.         if(type == I)
  68.             fprintf(trfp," NS=%d",(control>>1)&7);
  69.         /* Decode I field */
  70.         if(pullup(bpp,&pid,1) == 1){    /* Get pid */
  71.             switch(pid & (PID_FIRST | PID_LAST)){
  72.             case PID_FIRST:
  73.                 fprintf(trfp," First frag");
  74.                 break;
  75.             case PID_LAST:
  76.                 fprintf(trfp," Last frag");
  77.                 break;
  78.             case PID_FIRST|PID_LAST:
  79.                 break;    /* Complete message, say nothing */
  80.             case 0:
  81.                 fprintf(trfp," Middle frag");
  82.                 break;
  83.             }
  84.             fprintf(trfp," pid=");
  85.             switch(pid & 0x3f){
  86.             case PID_ARP:
  87.                 fprintf(trfp,"ARP\n");
  88.                 break;
  89.             case PID_NETROM:
  90.                 fprintf(trfp,"NET/ROM\n");
  91.                 break;
  92.             case PID_IP:
  93.                 fprintf(trfp,"IP\n");
  94.                 break;
  95.             case PID_NO_L3:
  96.                 fprintf(trfp,"Text\n");
  97.                 break;
  98.             default:
  99.                 fprintf(trfp,"0x%x\n",uchar(pid));
  100.             }
  101.             /* Only decode frames that are the first in a
  102.              * multi-frame sequence
  103.              */
  104.             switch(pid & (PID_PID | PID_FIRST)){
  105.             case PID_ARP | PID_FIRST:
  106.                 arp_dump(bpp);
  107.                 break;
  108.             case PID_IP | PID_FIRST:
  109.                 /* Only checksum complete frames */
  110.                 ip_dump(bpp,pid & PID_LAST);
  111.                 break;
  112.             case PID_NETROM | PID_FIRST:
  113.                 netrom_dump(bpp);
  114.                 break;
  115.             }
  116.             return;
  117.         }
  118.     } else if(type == FRMR && pullup(bpp,tmp,3) == 3){
  119.         fprintf(trfp,": %s Vr = %d Vs = %d",decode_type(ftype(tmp[0])),
  120.                 (tmp[1] >> 5) & MMASK,(tmp[1] >> 1) & MMASK);
  121.         if(tmp[2] & W)
  122.             fprintf(trfp," Invalid control field");
  123.         if(tmp[2] & X)
  124.             fprintf(trfp," Illegal I-field");
  125.         if(tmp[2] & Y)
  126.             fprintf(trfp," Too-long I-field");
  127.         if(tmp[2] & Z)
  128.             fprintf(trfp," Invalid seq number");
  129.     }
  130.     fprintf(trfp,"\n");
  131. }
  132. /* Display NET/ROM network and transport headers */
  133. static
  134. netrom_dump(bpp)
  135. struct mbuf **bpp;
  136. {
  137.     struct ax25_addr src,dest;
  138.     char x;
  139.     char tmp[16];
  140.     register int i;
  141.  
  142.     if(bpp == NULLBUFP || *bpp == NULLBUF)
  143.         return;
  144.     /* See if it is a routing broadcast */
  145.     if(uchar(*(*bpp)->data) == 0xff) {
  146.         pullup(bpp,tmp,1);        /* Signature */
  147.         pullup(bpp,tmp,ALEN);
  148.         tmp[ALEN] = '\0';
  149.         fprintf(trfp,"NET/ROM Routing: %s\n",tmp);
  150.         for(i = 0;i < 11;i++) {
  151.             if (pullup(bpp,tmp,AXALEN) < AXALEN)
  152.                 break;
  153.             memcpy(src.call,tmp,ALEN);
  154.             src.ssid = tmp[ALEN];
  155.             pax25(tmp,&src);
  156.             fprintf(trfp,"        %-12s",tmp);
  157.             pullup(bpp,tmp,ALEN);
  158.             tmp[ALEN] = '\0';
  159.             fprintf(trfp,"%8s",tmp);
  160.             pullup(bpp,tmp,AXALEN);
  161.             memcpy(src.call,tmp, ALEN);
  162.             src.ssid = tmp[ALEN];
  163.             pax25(tmp,&src);
  164.             fprintf(trfp,"    %-12s", tmp);
  165.             pullup(bpp,tmp,1);
  166.             fprintf(trfp,"    %3u\n",uchar(tmp[0]));
  167.         }
  168.         return;
  169.     }
  170.     /* Decode network layer */
  171.     pullup(bpp,tmp,AXALEN);
  172.     memcpy(src.call,tmp,ALEN);
  173.     src.ssid = tmp[ALEN];
  174.     pax25(tmp,&src);
  175.     fprintf(trfp,"NET/ROM n: %s",tmp);
  176.  
  177.     pullup(bpp,tmp,AXALEN);
  178.     memcpy(dest.call,tmp,ALEN);
  179.     dest.ssid = tmp[ALEN];
  180.     pax25(tmp,&dest);
  181.     fprintf(trfp,"->%s",tmp);
  182.  
  183.     pullup(bpp,&x,1);
  184.     fprintf(trfp," ttl %d\n",uchar(x));
  185.  
  186.     nettra_dump(bpp);        /* dump transport layer */
  187. }
  188.  
  189. /* Display NET/ROM transport header or IP datagram */
  190. nettra_dump(bpp)
  191. struct mbuf **bpp;
  192. {
  193.     struct ax25_addr src,dest;
  194.     char x;
  195.     char tmp[16];
  196.     char thdr[5];
  197.     struct mbuf *thbuf,*qdata();
  198.  
  199.     /* Read first five bytes of "transport" header */
  200.     if (pullup(bpp,thdr,5) != 5)
  201.         return;
  202.  
  203.     /* check if it is a net/rom transport layer packet */
  204.     /* sorry, but this can only be guessed... */
  205.     /* new encapsulation method uses NET/ROM transport opcode 0 */
  206.     if ((thdr[0] & 0xf0) != (IPVERSION << 4) && (x = thdr[4] & 0xf) <= 6){
  207.         if (x == 0){    /* IP datagram (new encapsulation method) */
  208.         ip_dump(bpp,1);
  209.         return;
  210.         }
  211.  
  212.         /* opcode 1..6, and first byte does not look like IP */
  213.         /* it most probably is a NET/ROM transport layer packet */
  214.         fprintf(trfp,"NET/ROM t: ");
  215.         switch(x){
  216.         case 1: /* Connect request */
  217.         pullup(bpp,&x,1);
  218.         fprintf(trfp,"conn rqst: ckt %d/%d wnd %d",
  219.                  uchar(thdr[0]),uchar(thdr[1]),uchar(x));
  220.         pullup(bpp,(char *)&src,AXALEN);
  221.         pax25(tmp,&src);
  222.         fprintf(trfp," %s",tmp);
  223.         pullup(bpp,(char *)&dest,AXALEN);
  224.         pax25(tmp,&dest);
  225.         fprintf(trfp,"->%s",tmp);
  226.         break;
  227.         case 2: /* Connect acknowledgement */
  228.         pullup(bpp,&x,1);
  229.         fprintf(trfp,"conn ack: ur ckt %d/%d my ckt %d/%d wnd %d",
  230.                  uchar(thdr[0]),uchar(thdr[1]),uchar(thdr[2]),
  231.                  uchar(thdr[3]),uchar(x));
  232.         break;
  233.         case 3: /* Disconnect request */
  234.         fprintf(trfp,"disc: ckt %d/%d",
  235.                  uchar(thdr[0]),uchar(thdr[1]));
  236.         break;
  237.         case 4: /* Disconnect acknowledgement */
  238.         fprintf(trfp,"disc ack: ckt %d/%d",
  239.                  uchar(thdr[0]),uchar(thdr[1]));
  240.         break;
  241.         case 5: /* Information (data) */
  242.         fprintf(trfp,"info: ckt %d/%d txseq %d rxseq %d",
  243.                  uchar(thdr[0]),uchar(thdr[1]),
  244.                  uchar(thdr[2]),uchar(thdr[3]));
  245.         break;
  246.         case 6: /* Information acknowledgement */
  247.         fprintf(trfp,"info ack: ckt %d/%d rxseq %d",
  248.                  uchar(thdr[0]),uchar(thdr[1]),uchar(thdr[3]));
  249.         break;
  250.         }
  251.         if(thdr[4] & 0x80)
  252.         fprintf(trfp," CHOKE");
  253.         if(thdr[4] & 0x40)
  254.         fprintf(trfp," NAK");
  255.         if(thdr[4] & 0x20)
  256.         fprintf(trfp," MORE");
  257.         fprintf(trfp,"\n");
  258.     } else {
  259.         /* maybe it's an IP datagram! (old encapsulation method) */
  260.         /* the following is gross and disgusting */
  261.         if((thbuf = qdata(thdr,5)) != NULLBUF){
  262.         thbuf->next = *bpp;
  263.         *bpp = thbuf;
  264.         fprintf(trfp,"?");    /* indicate old method */
  265.         ip_dump(bpp,1);
  266.         }
  267.     }
  268. }
  269. char *
  270. decode_type(type)
  271. int16 type;
  272. {
  273.     switch(uchar(type)){
  274.     case I:
  275.         return "I";
  276.     case RR:
  277.         return "RR";
  278.     case RNR:
  279.         return "RNR";
  280.     case REJ:
  281.         return "REJ";
  282.     case SREJ:
  283.         return "SREJ";
  284.     case UI:
  285.         return "UI";
  286.     case SIM:
  287.         return "SIM";
  288.     case DM:
  289.         return "DM";
  290.     case UP:
  291.         return "UP";
  292.     case SABM:
  293.         return "SABM";
  294.     case DISC:
  295.         return "DISC";
  296.     case SARME:
  297.         return "SARME";
  298.     case UA:
  299.         return "UA";
  300.     case SABME:
  301.         return "SABME";
  302.     case SNRM:
  303.         return "SNRM";
  304.     case XID:
  305.         return "XID";
  306.     case FRMR:
  307.         return "FRMR";
  308.     case RSET:
  309.         return "RSET";
  310.     case SNRME:
  311.         return "SNRME";
  312.     case TEST:
  313.         return "TEST";
  314.     default:
  315.         return "[invalid]";
  316.     }
  317. }
  318.  
  319.